/*
 * @Author: 来自火星的码农 15122322+heyzhi@user.noreply.gitee.com
 * @Date: 2025-10-10 11:31:41
 * @LastEditors: 来自火星的码农 15122322+heyzhi@user.noreply.gitee.com
 * @LastEditTime: 2025-10-30 15:26:38
 * @FilePath: /GateServer/src/mysql/mysqldao.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "mysqldao.h"
#include "../util/config.h"
#include "mysqlconnectionpool.h"
#include <algorithm>
#include <cppconn/connection.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <memory>
#include <string>
#include <sys/stat.h>
#include <mysql_driver.h>
#include <mysql_connection.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#include "../util/util.h"
namespace Yizhi {
    static ConfigVar<std::string>::ptr g_mysql_host=ConfigMgr::Lookup("mysqlport",(std::string)"127.0.0.1","");
    static ConfigVar<std::string>::ptr g_mysql_psw=ConfigMgr::Lookup("mysql.password",(std::string)"Zsby+99924","");
    static ConfigVar<int >::ptr g_mysql_port=ConfigMgr::Lookup("mysql.port",(int)3306,"");
    static ConfigVar<std::string>::ptr g_mysql_schema=ConfigMgr::Lookup("mysql.schema",(std::string)"Yzchat");

    static ConfigVar<std::string>::ptr g_mysql_username=ConfigMgr::Lookup("msyql.username",(std::string)"root","");

    MysqlDao::MysqlDao(){
        std::string url=g_mysql_host->getvalue()+":"+std::to_string(g_mysql_port->getvalue());
        std::string username=g_mysql_username->getvalue();
        std::string psw=g_mysql_psw->getvalue();
        std::string schema=g_mysql_schema->getvalue();
        m_conpool.reset(new MysqlConnectionPool(url,username,psw,schema,5));
    }
    MysqlDao::~MysqlDao(){
        m_conpool->close();
    }

    int MysqlDao::RegUser(std::string username,std::string email,std::string psw){
        auto con=m_conpool->GetConnection();
        try {
            if(con==nullptr){
                //m_conpool->ReturnConnection(std::move(con));
                return -1;
            }

            std::unique_ptr<sql::PreparedStatement>prestmt(con->prepareStatement("CALL reg_user(?,?,?,@result)"));

            prestmt->setString(1,username);
            prestmt->setString(2,email);
            prestmt->setString(3,psw);

            prestmt->execute();

            std::unique_ptr<sql::Statement> stmtResult(con->createStatement());
            std::unique_ptr<sql::ResultSet> res(stmtResult->executeQuery("SELECT @result As result"));

            if(res->next()){
                int result=res->getInt("result");
                LOG_DEBUG("result:"+std::to_string(result));
                m_conpool->ReturnConnection(std::move(con));
                return result;
            }

            return -1;


        } catch (sql::SQLException &e) {
              LOG_ERROR("sql errot: ");
              LOG_ERROR(e.getSQLStateCStr());
              m_conpool->ReturnConnection(std::move(con));
        }
        return -1;
    }

    bool MysqlDao::findUser(std::string username,std::string email){

        auto con=m_conpool->GetConnection();

        try {
            if(con==nullptr){
                m_conpool->ReturnConnection(std::move(con));
                return false;
            }
            std::unique_ptr<sql::PreparedStatement> prestmt(con->prepareStatement(
                "SELECT count(*) FROM user WHERE username=? OR email=?"
            ));

            prestmt->setString(1,username);
            prestmt->setString(2,email);

            std::unique_ptr<sql::ResultSet> res(prestmt->executeQuery());

            if(res->next()){
                int count=res->getInt("count")>0;
                m_conpool->ReturnConnection(std::move(con));
                return count>0;
            }
            return false;
        } catch (sql::SQLException& e) {
            LOG_ERROR(e.getSQLStateCStr());
            m_conpool->ReturnConnection(std::move(con));
        }
        return false;
    }

    int MysqlDao::ResetPsw(std::string username,std::string email,std::string psw){
        auto con=m_conpool->GetConnection();
        try {
            
            if(con==nullptr){
               // m_conpool->ReturnConnection(con);
                return 0;
            }
              std::unique_ptr<sql::PreparedStatement> prestmt(con->prepareStatement(
                "UPDATE user SET password=? WHERE email=?"
            ));
            prestmt->setString(1, psw);
            prestmt->setString(2,email);

            std::unique_ptr<sql::ResultSet> res(prestmt->executeQuery());

            if(res->next()){
                m_conpool->ReturnConnection(std::move(con));
                return 1;
            }
        
        } catch (sql::SQLException&e) {
            LOG_ERROR(e.getSQLStateCStr());
             m_conpool->ReturnConnection(std::move(con));    
        }
        return 0;
    }

    bool MysqlDao::findUserbyeamil(const std::string&email){
        auto con=m_conpool->GetConnection();
        try {
            
            if(con==nullptr){
               // m_conpool->ReturnConnection(con);
                return 0;
            }
              std::unique_ptr<sql::PreparedStatement> prestmt(con->prepareStatement(
                "SELECT count(*) FROM user WHERE email=?"
            ));
           
            prestmt->setString(1,email);

            std::unique_ptr<sql::ResultSet> res(prestmt->executeQuery());

            if(res->next()){
                m_conpool->ReturnConnection(std::move(con));
                return true;
            }
        
        } catch (sql::SQLException&e) {
            LOG_ERROR(e.getSQLStateCStr());
             m_conpool->ReturnConnection(std::move(con));    
        }
        return false;
    }


    int MysqlDao::login(std::string username,std::string psw){
        
        

        try {
            auto con=m_conpool->GetConnection();

            if(con==nullptr){
                return false;
            }
            Defer defer([this,&con](){
                m_conpool->ReturnConnection(std::move(con));
            });


            std::unique_ptr<sql::PreparedStatement> prestmt(con->prepareStatement(
                    "SELECT password,uid FROM user WHERE username=?"
                ));
            
                prestmt->setString(1,username);

                std::unique_ptr<sql::ResultSet> res(prestmt->executeQuery());
                std::string orgin_psw="";
                if(!res->next()){
                    LOG_ERROR("sqlError,user not exit");
                    return false;
                }
                orgin_psw=res->getString("password");
                if(orgin_psw==psw){
                    auto uid=res->getInt("uid");
                    return uid;
                }
                else {
                    return -1;
                }

        } catch (sql::SQLException&e) {
            LOG_ERROR(e.getSQLStateCStr());
            
        }
        
        return false;
    }

    User MysqlDao::getUserbyId(int id){

         try {
            auto con=m_conpool->GetConnection();

            if(con==nullptr){
                return {};
            }
            Defer defer([this,&con](){
                m_conpool->ReturnConnection(std::move(con));
            });


            std::unique_ptr<sql::PreparedStatement> prestmt(con->prepareStatement(
                    "SELECT * FROM user WHERE uid=?"
                ));
                prestmt->setInt(1,id);
                 std::unique_ptr<sql::ResultSet> res(prestmt->executeQuery());
                if(!res->next()){
                    LOG_ERROR("sqlError,user not exit");
                    return {};
                }


                User user;
                user.setUid(id);
                user.setUsername(res->getString("username"));
                user.setEmail(res->getString("email"));

                LOG_DEBUG(user.getEmail()+"ddd");
                
                return user;
        } catch (sql::SQLException&e) {
            LOG_ERROR(e.getSQLStateCStr());
            
        }
        
        

        return {};
    }




}